package com.choosefine.common.url;

import com.choosefine.common.url.entity.RegisterDto;
import com.choosefine.common.url.entity.UrlDto;
import com.choosefine.common.utils.PropertiesUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Author Ye_Wenda
 * @Date 4/6/2017
 *
 * Add ignore authority check property.
 * @Author Ye_Wenda
 * @Date 4/25/2017
 */
public class UrlRegistrar {

    private final static Logger logger = LoggerFactory.getLogger(UrlRegistrar.class);

    private UrlService urlService = new UrlService();

    private RequestMappingHandlerMapping requestMappingHandlerMapping;
    private RestTemplate restTemplate;
    private String serviceName;
    private String dmsUrl;    private List<String> ignoreUrls;

    public UrlRegistrar(RequestMappingHandlerMapping requestMappingHandlerMapping, RestTemplate restTemplate, String serviceName, String dmsUrl) {
        this(requestMappingHandlerMapping, restTemplate, serviceName, dmsUrl, null);
    }

    public UrlRegistrar(RequestMappingHandlerMapping requestMappingHandlerMapping, RestTemplate restTemplate, String serviceName, String dmsUrl, List<String> ignoreUrls) {
        this.requestMappingHandlerMapping = requestMappingHandlerMapping;
        this.restTemplate = restTemplate;
        this.serviceName = serviceName;
        this.dmsUrl = dmsUrl;
    }

    @Async
    public void send() {
        RegisterDto registerDto = new RegisterDto();
        registerDto.setServiceName(serviceName);
        registerDto.setUrlList(new ArrayList<>());
        Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
        for (RequestMappingInfo info : map.keySet()) {
            Set<String> urls = info.getPatternsCondition().getPatterns();
            for (String url : urls) {
                Set<RequestMethod> methods = info.getMethodsCondition().getMethods();
                for (RequestMethod method : methods) {
                    String methodStr = method.name();
                    UrlDto urlDto = new UrlDto();
                    urlDto.setUrl(urlService.formatUrl(url));
                    urlDto.setMethod(methodStr);
                    if (ignoreUrls != null && ignoreUrls.size() != 0 && ignoreUrls.contains(urlDto.getUrl())) {
                        urlDto.setPerm(UrlDto.ANON);
                    } else {
                        urlDto.setPerm(UrlDto.AUTHC);
                    }
                    registerDto.getUrlList().add(urlDto);
                }
            }
        }
        try {
            HttpEntity<RegisterDto> requestEntity = new HttpEntity<>(registerDto);
            String dmsRegisterUrl = (String) PropertiesUtil.getProperties().get("dms.registerUrl");
            ResponseEntity<String> responseEntity = restTemplate.exchange(dmsUrl + dmsRegisterUrl, HttpMethod.POST, requestEntity, String.class);
            String returnStr = responseEntity.getBody();
            logger.info("Choosefine Common: " + returnStr);
        } catch (Exception e) {
            logger.error("注册urls失败！", e);
        }
    }
}
